namespace DotNetNuke.Services.Cache.BroadcastPollingCachingProvider
{
    using DotNetNuke.Common;
    using DotNetNuke.Common.Utilities;
    using DotNetNuke.Framework.Providers;
    using DotNetNuke.Services.Cache;
    using System;
    using System.Collections;
    using System.Runtime.CompilerServices;
    using System.Web;
    using System.Web.Caching;

    public class BPCachingProvider : CachingProvider
    {
        private static Cache _objCache;
        private ProviderConfiguration _providerConfiguration = ProviderConfiguration.GetProviderConfiguration("caching");
        private const string ProviderType = "caching";

        public override object Add(string Key, object Value, CacheDependency Dependencies, DateTime AbsoluteExpiration, TimeSpan SlidingExpiration, CacheItemPriority Priority, CacheItemRemovedCallback OnRemoveCallback)
        {
            return objCache.Add(Key, (Value), Dependencies, AbsoluteExpiration, SlidingExpiration, Priority, OnRemoveCallback);
        }

        public override IDictionaryEnumerator GetEnumerator()
        {
            return objCache.GetEnumerator();
        }

        public override object GetItem(string CacheKey)
        {
            object obj = (objCache[CacheKey]);
            if (obj != null)
            {
                return objCache[CacheKey];
            }
            return obj;
        }

        public override object GetPersistentCacheItem(string CacheKey, Type objType)
        {
            object obj = (objCache[CacheKey]);
            if ((obj == null) && DataCache.CachePersistenceEnabled)
            {
                Controller c = new Controller();
                obj = (c.GetCachedObject(CacheKey, objType));
                if (obj != null)
                {
                    this.Insert(CacheKey, (obj), true);
                }
            }
            return obj;
        }

        public override void Insert(string CacheKey, object objObject, bool PersistAppRestart)
        {
            if (PersistAppRestart)
            {
                this.Remove(CacheKey);
            }
            Controller c = new Controller();
            if (PersistAppRestart & DataCache.CachePersistenceEnabled)
            {
                c.AddCachedObject(CacheKey, (objObject), Globals.ServerName);
                c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
            }
            else if (Globals.WebFarmEnabled)
            {
                c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
            }
            objCache.Insert(CacheKey, (objObject));
        }

        public override void Insert(string CacheKey, object objObject, CacheDependency objDependency, bool PersistAppRestart)
        {
            if (PersistAppRestart)
            {
                this.Remove(CacheKey);
            }
            Controller c = new Controller();
            if (PersistAppRestart & DataCache.CachePersistenceEnabled)
            {
                c.AddCachedObject(CacheKey, (objObject), Globals.ServerName);
                c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
            }
            else if (Globals.WebFarmEnabled)
            {
                c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
            }
            objCache.Insert(CacheKey, (objObject), objDependency);
        }

        public override void Insert(string CacheKey, object objObject, CacheDependency objDependency, DateTime AbsoluteExpiration, TimeSpan SlidingExpiration, bool PersistAppRestart)
        {
            if (PersistAppRestart)
            {
                this.Remove(CacheKey);
            }
            Controller c = new Controller();
            if (PersistAppRestart & DataCache.CachePersistenceEnabled)
            {
                c.AddCachedObject(CacheKey, (objObject), Globals.ServerName);
                c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
            }
            else if (Globals.WebFarmEnabled)
            {
                c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
            }
            objCache.Insert(CacheKey, (objObject), objDependency, AbsoluteExpiration, SlidingExpiration);
        }

        public override void Insert(string CacheKey, object objObject, CacheDependency objDependency, DateTime AbsoluteExpiration, TimeSpan SlidingExpiration, CacheItemPriority Priority, CacheItemRemovedCallback OnRemoveCallback, bool PersistAppRestart)
        {
            if (PersistAppRestart)
            {
                this.Remove(CacheKey);
            }
            Controller c = new Controller();
            if (PersistAppRestart & DataCache.CachePersistenceEnabled)
            {
                c.AddCachedObject(CacheKey, (objObject), Globals.ServerName);
                c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
            }
            else if (Globals.WebFarmEnabled)
            {
                c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
            }
            objCache.Insert(CacheKey, (objObject), objDependency, AbsoluteExpiration, SlidingExpiration, Priority, OnRemoveCallback);
        }

        public override string PurgeCache()
        {
            return "The Broadcast/Polling-Based Caching Provider does not require the PurgeCache feature.";
        }

        public override void Remove(string CacheKey)
        {
            if (objCache[CacheKey] != null)
            {
                Controller c = new Controller();
                objCache.Remove(CacheKey);
                if (Globals.WebFarmEnabled)
                {
                    c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
                }
            }
        }

        public override void RemovePersistentCacheItem(string CacheKey)
        {
            if (objCache[CacheKey] != null)
            {
                objCache.Remove(CacheKey);
                if (DataCache.CachePersistenceEnabled)
                {
                    Controller c = new Controller();
                    c.DeleteCachedObject(CacheKey);
                    c.AddBroadcast("RemoveCachedItem", CacheKey, Globals.ServerName);
                }
            }
        }

        private static Cache objCache
        {
            get
            {
                if (_objCache == null)
                {
                    _objCache = HttpRuntime.Cache;
                }
                return _objCache;
            }
        }
    }
}

